<?php

/**
 * Albireo Kernel
 *
 * @copyright  Copyright (c) 2010 Albireo Solutions
 * @package    Kernel
 */

use \DibiException;

use Nette\Object;
use Nette\Security\Permission;

use Albireo\Mode;
use Celebrio\AccessControl\AclConstants;

use \InvalidStateException;

/**
 * KernelAcl creates authorization rules
 *
 * @author Albireo Solutions
 */

//TODO: MAKE IT CACHED
//TODO odebrat zbytecne Permission::all
class KernelAcl extends Permission {

    /**
     * Creates ACL authorization rules
     * (explicitly and from Database)
     */
    public function __construct() {

        $this->addRole(AclConstants::NETTE_GUEST);

        $this->addRole(AclConstants::GUEST_ROLE);
        $this->addRole(AclConstants::ROOT_ROLE);
        $this->addRole(AclConstants::MASTERADMIN_DB);

        $this->addResource('Kernel:Error');
        $this->addResource('Kernel:SignIn');
        $this->addResource('Kernel:SignOut');
        $this->addResource('Kernel:Overview');
        
        $this->addResource('Kernel:Modules:ModulesManagement');
        $this->addResource('Kernel:Modules:DatabaseManagement');
        $this->addResource('Kernel:Modules:Console');

        $this->addResource('Kernel:Logs:Overview');
        $this->addResource('Kernel:Logs:Error');
        $this->addResource('Kernel:Logs:Php:Process');
        $this->addResource('Kernel:Logs:Php:Display');
        $this->addResource('Kernel:Logs:Php:Detail');
        $this->addResource('Kernel:Logs:Logger:Display');
        $this->addResource('Kernel:Logs:Acl:Display');
        $this->addResource('Kernel:Logs:Performance:Display');

        $this->addResource('Kernel:FileSystemManagement');
        $this->addResource('Kernel:UsersManagement');

        $this->addResource("Webtop:Default");
        $this->addResource("Webtop:Sign");

        $this->allow(AclConstants::MASTERADMIN_DB);
        $this->allow(Permission::ALL,'Kernel:SignIn');
        $this->allow(Permission::ALL,'Kernel:SignOut');
        
        $this->allow(Permission::ALL,'Webtop:Sign');

        $this->allow(Permission::ALL,'Webtop:Default', 'default');
        $this->allow(Permission::ALL,'Webtop:Default', 'getapps');



        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Overview','default');
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Overview','info');
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Error', Permission::ALL);

        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Logs:Overview', Permission::ALL);
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Logs:Error', Permission::ALL);

        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Logs:Php:Process', Permission::ALL);
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Logs:Php:Display', Permission::ALL);
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Logs:Php:Detail', Permission::ALL);
        
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Logs:Logger:Display', Permission::ALL);
        
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Logs:Performance:Display', Permission::ALL);

        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Modules:ModulesManagement', Permission::ALL);
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Modules:DatabaseManagement', 'default');
        $this->allow(AclConstants::ROOT_ROLE, 'Kernel:Modules:Console', Permission::ALL);

        if (Mode::isCritical() === FALSE) {
            
            // registration is accessible for all in the normal mode
            $this->addResource('Kernel:Users:Users');
            $this->allow(Permission::ALL,'Kernel:Users:Users', 'register');
            
            $model = new KernelAclModel();
            try {
                foreach($model->getRoles() as $role) {
                    try {
                        $this->addRole($role->name, $role->parent_name);
                    } catch (InvalidStateException $ex) {
                        //throw $ex;
                    }
                }

                foreach($model->getResources() as $resource) {
                    try {
                        $this->addResource($resource->name);
                    } catch (InvalidStateException $ex) {
                        //throw $ex;
                    }
                }

                foreach($model->getRules() as $rule) {
                    try {
                        if ($rule->allowed) {
                            //assign the rule to the list
                            $this->allow($rule->role, $rule->resource, $rule->privilege);
                        } else {
                            $this->allow($rule->role, $rule->resource, $rule->privilege);
                        }
                    } catch (InvalidStateException $ex) {
                        //TODO: Control
                    }
                }
            } catch (DibiException $e) {
                throw $e;
                //Mode::setCriticalMode(_("Kernel is in Critical Mode! Database or ACL tables are unavailable.")." ".$e->getMessage());
            }
        }
    }
}